<template>
  <div class="page_root" data-page-name="项目看板" data-page-identification="q_tuvnfkjbh5">
    <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
      <!-- begin vid_t24nxlyepr 容器_uff5rjjne5 -->
      <al-box class="vid_t24nxlyepr">
        <!-- begin vid_iggljq0jjk 自定义模板_wn2w3ezp1c -->
        <div class="body">
          <div class="tree-box">
            <a-input-search v-model:value="searchValue" placeholder="请输入查询关键字" @change="onChange"
              style="margin: 20px auto;" />
            <a-tree v-if="treeData && treeData.length > 0" :autoExpandParent="autoExpandParent" @expand="onExpand"
              v-model:expandedKeys="expandedKeys" :fieldNames="fieldNames" v-model:selectedKeys="selectedKeys" show-line
              :tree-data="treeData" @select="treeSelect">
              <template #title="{ projectName, id, children, parentId }">
                <span> {{ projectName }}</span>
              </template>
            </a-tree>
          </div>
          <div class="right-box">
            <div class="back-ground">{{ projectData.projectName }}
              <span v-if="projectData.projectName" class="title">[ {{
                projectData.startTime }}~{{
    projectData.endTime }} {{ projectData.plName }} ] </span>
            </div>
            <!-- 里程碑进度 -->
            <div class="main">
              <div class="progress">
                <div class="col"> 进度里程碑</div>
                <div class="no-progress" v-if="milestoneDataList.length == 0">
                  <div class="tip">
                    <p class="message">暂无进度里程碑</p>
                  </div>
                </div>
                <div class="timeaxis" v-if="milestoneDataList.length > 0">
                  <template v-for="(item, index) in milestoneDataList" :key="item.id">
                    <div class="box">
                      <div class="item">
                        <p class="cercle" v-if="index === 0"></p>
                        <caret-right-filled class="arrow" v-if="index === milestoneDataList.length - 1" />
                        <div class="center">{{ item.milepostName }}</div>
                      </div>
                      <div class="circular">
                        <a-tooltip :overlayStyle="overlayStyle">
                          <template #title>
                            <!-- <div style="width:326px ; height: 200px;"> -->
                            <a-row style="margin-top: 5px;margin-left: 5px;margin-right: 3px; ">
                              <a-col :span="11" class="tip-tool" style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">状态：</p>
                                <p style="font-size: 14px; font-weight: 600; font-family: PingFangSC-Semibold;">{{
                                  item.milepostStatus }}</p>
                              </a-col>

                              <a-col :span="11" offset="2" class="tip-tool"
                                style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">当前进度：</p>
                                <span style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.finishSchedule }}%</span>
                              </a-col>
                            </a-row>
                            <a-row style="margin-left: 5px; margin-right: 3px;">
                              <a-col :span="11" class="tip-tool" style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">总任务数：</p>
                                <p style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.taskNum }}</p>
                              </a-col>
                              <a-col :span="11" offset="2" class="tip-tool"
                                style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">完成任务数：</p>
                                <p style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.sumFinishNum }}</p>
                              </a-col>
                            </a-row>
                            <a-row style="margin-left: 5px; margin-right: 3px;">
                              <a-col :span="11" class="tip-tool" style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">未完成任务数：</p>
                                <p style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.unFinishNum }}</p>
                              </a-col>
                              <a-col :span="11" offset="2" class="tip-tool"
                                style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">正常完成任务数：</p>
                                <p style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.finishNum }}</p>
                              </a-col>
                            </a-row>
                            <a-row style="margin-left: 5px; margin-right: 3px;">
                              <a-col :span="11" class="tip-tool" style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">延迟完成任务数：</p>
                                <p style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.postponeFinishNum }}</p>
                              </a-col>
                              <a-col :span="11" offset="2" class="tip-tool"
                                style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">进行中任务数：</p>
                                <p style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.underwayNum }}</p>
                              </a-col>
                            </a-row>
                            <a-row style="margin-left: 5px; margin-right: 3px;">
                              <a-col :span="11" class="tip-tool" style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">延期任务数：</p>
                                <p style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.postponeNum }}</p>
                              </a-col>
                              <a-col :span="11" offset="2" class="tip-tool"
                                style=" display:flex;justify-content: space-between;">
                                <p style="font-size: 14px; font-family: PingFangSC-Regular; opacity: 0.8;">未启动任务数：</p>
                                <p style="font-size: 14px; font-weight: 600;font-family: PingFangSC-Semibold;">{{
                                  item.unStartNum }}</p>
                              </a-col>
                            </a-row>
                            <!-- </div> -->
                          </template>
                          <!-- <div class="no-start">
                 </div> -->
                          <div class="circular" :id="`chart${index}`"> </div>
                        </a-tooltip>
                      </div>
                      <div class="detailed-information">
                        <div class="message">
                          <p class="plan">计划开始：{{ item.startTime }}</p>
                          <p class="plan">实际开始：{{ item.actualStartTime }}</p>
                          <p class="plan">计划完成：{{ item.endTime }}</p>
                          <p class="plan">实际完成：{{ item.actualFinishTime }}
                            <span v-if="item.delayDay !== null"><a-tag class="tag-day">延期{{ item.delayDay
                            }}</a-tag></span>
                          </p>
                          <a-tag class="plan-count" v-if="item.changeNum !== 0">变更{{ item.changeNum }}次</a-tag>
                        </div>
                      </div>
                    </div>
                  </template>
                </div>
              </div>
              <!-- END 里程碑进度 -->

              <!-- 回款里程碑 -->
              <div class="collection">
                <!-- <a-card> -->
                <div class="collection-col"> 回款里程碑 </div>
                <div class="add-edit-btns">
                  <div ghost class="collection-btn" @click="addCollection"><plus-square-outlined class="icon" />新增</div>
                  <div ghost class="collection-btn" @click="editCollection"><edit-outlined class="icon" />编辑</div>
                </div>
                <div class="no-collection" v-if="collectionList.length == 0">
                  <div class="tip">
                    <p class="message">请点击右上角，<span>新增回款里程碑</span></p>
                  </div>
                </div>
                <div class="collection-message-group" v-if="collectionList.length > 0">
                  <div class="collection-message" v-for="(item, index) in collectionList">
                    <span class="order">{{ index + 1 }}</span>
                    <a-tooltip>
                      <template #title> {{ item.paymentMilepostName }}({{ item.proportion }}) </template>

                      <p class="collection-message-title">{{ item.paymentMilepostName }}({{ item.proportion }})</p>
                    </a-tooltip>
                    <!-- 全绿 -->
                    <!-- 全绿 -->
                    <p class="payment-received"
                      v-if="item.actuallyPaymentTime && new Date(item.actuallyPaymentTime) <= new Date(item.currentPlanTime)">
                      <span class="title"><check-circle-filled class="icon" />已回款</span>
                      <span class="finish-money">{{
                        item.money



                      }}<span class="finish-unit"> 万元</span>
                        <a-tag class="money-tag" v-if="item.delayTime > 0"
                          style=" position: absolute; top: 65%; left: 73%; z-index: 999; border-radius: 10px; font-size: 8px; margin-left: 0; font-weight: 400;">延期{{
                            item.delayTime



                          }}天</a-tag></span>
                    </p>
                    <!-- 红绿 -->
                    <p class="payment-received"
                      v-if="item.actuallyPaymentTime && new Date(item.actuallyPaymentTime) > new Date(item.currentPlanTime)">
                      <span class="title"><check-circle-filled class="icon" style="color: #FF2A00;" />已回款</span>
                      <span class="finish-money">{{
                        item.money



                      }}<span class="finish-unit"> 万元</span>
                        <a-tag class="money-tag" v-if="item.delayTime > 0"
                          style=" position: absolute; top: 65%; left: 73%; z-index: 999; border-radius: 10px; font-size: 8px; margin-left: 0; font-weight: 400;">延期{{
                            item.delayTime



                          }}天</a-tag></span>
                    </p>
                    <!-- 全红 -->
                    <p class="tobe-collected-received"
                      v-if="!item.actuallyPaymentTime && new Date(item.currentPlanTime) < new Date()">待回款
                      <span class="fail-money">{{
                        item.money



                      }}<span class="fail-unit"> 万元</span><a-tag class="money-tag" v-if="item.delayTime > 0"
                          style=" position: absolute; top: 65%; left: 73%; z-index: 999; border-radius: 10px; font-size: 8px; margin-left: 0; font-weight: 400;">延期{{
                            item.delayTime



                          }}天</a-tag></span>
                    </p>
                    <!-- 灰色 -->
                    <p class="uncollected-payment"
                      v-if="!item.actuallyPaymentTime && new Date(item.currentPlanTime) > new Date()">待回款
                      <span class="uncollected-money">{{
                        item.money



                      }}<span class="uncollected-unit"> 万元</span><a-tag class="money-tag" v-if="item.delayTime > 0"
                          style=" position: absolute; top: 65%; left: 73%; z-index: 999; border-radius: 10px; font-size: 8px; margin-left: 0; font-weight: 400;">延期{{
                            item.delayTime



                          }}天</a-tag></span>
                    </p>
                    <a-divider class="divider-line" />
                    <p class="milepost-date">
                      最初计划：{{ item.planPaymentTime }}<br />
                      当前计划：{{ item.currentPlanTime }}<br />
                      实际回款：{{ item.actuallyPaymentTime }}
                    </p>
                    <a-button class="accomplish" v-if="item.actuallyPaymentTime" disabled>已完成</a-button>
                    <a-button class="noAccomplish" type="primary" ghost v-else @click="confirm(item.id)">完成</a-button>
                  </div>
                </div>
              </div>
              <div class="cost-analysis">
                <div class="collection-analysis">
                  <div class="cost-col">回款分析</div>
                  <div class="left-cost-chart">
                    <div ref="costChart" style="width: 40%; height: 200px"> </div>
                    <div v-if="totalProjectAmount" style="
                          flex: 1;
                          display: flex;
                          flex-direction: column;
                          justify-content: space-around;
                          height: 118px;
                          margin-top: 9%;
                      ">
                      <hr class="hr-money" />
                      <div>
                        <div style="line-height: 40px">
                          <div style="
                                      width: 10px;
                                      height: 10px;
                                      border-radius: 10px;
                                      background-color: #3875FF;
                                      display: inline-block;
                                      margin-right: 5px;
                                  ">
                          </div>
                          <span style="font-size: 15px">已回款
                            <span style="
                                              font-size: 26px;
                                              font-weight: 600;
                                              position: relative;
                                              height: 34px;
                                              display: inline-block;
                                              width: 131px;
                                              text-align: right;
                                          ">
                              {{ collectionMoneyData[0].value }}
                            </span>

                            万元</span>
                        </div>
                      </div>
                      <hr class="hr-money" />
                      <div style="line-height: 40px">
                        <div style="
                                  width: 10px;
                                  height: 10px;
                                  border-radius: 10px;
                                  background-color: #FF8448;
                                  display: inline-block;
                                  margin-right: 5px;
                              ">
                        </div>

                        <span style="font-size: 15px">待回款
                          <span style="
                                          font-size: 26px;
                                          font-weight: 600;
                                          height: 34px;
                                          position: relative;
                                          display: inline-block;
                                          width: 128px;
                                          text-align: right;
                                      ">
                            {{ collectionMoneyData[1].value }}
                          </span>
                          万元</span>
                      </div>
                      <hr class="hr-money" />
                    </div>
                  </div>
                </div>
                <div class="prime-analysis">
                  <div class="cost-col">成本分析</div>
                  <div class="content-cost" v-if="false">
                    <div class="right-chart">
                      <div ref="primeChart" style="height: 200px; width: 42%"></div>
                      <div class="right-tip">
                        <div v-if="projectBudgetAmount" style="
                                  flex: 1;
                                  display: flex;
                                  flex-direction: column;
                                  justify-content: space-around;
                                  height: 118px;
                                  margin-top: 17%;
                              ">
                          <hr class="hr-money" />
                          <div>
                            <div style="line-height: 40px">
                              <div style="
                                              width: 10px;
                                              height: 10px;
                                              border-radius: 10px;
                                              background-color: #3875FF;
                                              display: inline-block;
                                              margin-right: 5px;
                                          ">
                              </div>
                              <span style="font-size: 15px">总人力成本
                                <span style="
                                                      font-size: 26px;
                                                      height: 34px;
                                                      font-weight: 600;
                                                      position: relative;
                                                      display: inline-block;
                                                      width: 121px;
                                                      text-align: right;
                                                  ">
                                  {{ projectBudget[0].value }}
                                </span>
                                万元</span>
                            </div>
                          </div>
                          <hr class="hr-money" />
                          <div style="line-height: 40px">
                            <div style="
                                          width: 10px;
                                          height: 10px;
                                          border-radius: 10px;
                                          background-color: #FF8448;
                                          display: inline-block;
                                          margin-right: 5px;
                                      ">
                            </div>

                            <span style="font-size: 15px">总直接费用
                              <span style="
                                                  font-size: 26px;
                                                  height: 34px;
                                                  font-weight: 600;
                                                  position: relative;
                                                  display: inline-block;
                                                  width: 122px;
                                                  text-align: right;
                                              ">
                                {{ projectBudget[1].value }}
                              </span>
                              万元</span>
                          </div>
                          <hr class="hr-money" />
                        </div>
                      </div>
                    </div>
                    <div class="prime-right">
                      <a-row>
                        <a-col :span="18">
                          <span style="line-height: 50px; font-size: 15px">已发生人力成本
                            <span style="
                                              font-size: 26px;
                                              height: 40px;
                                              font-weight: 600;
                                              position: relative;
                                              display: inline-block;
                                              width: 125px;
                                              text-align: right;
                                          ">
                              {{ LaborCosts[0].money }}
                            </span>
                            万元</span>
                        </a-col>
                        <a-col :span="6">
                          <div class="progress-bar" ref="progressBar" style="height: 50px"></div>
                        </a-col>
                      </a-row>
                      <a-row>
                        <a-col :span="18">
                          <span style="line-height: 50px; font-size: 15px">已发生直接费用
                            <span style="
                                              font-size: 26px;
                                              height: 40px;
                                              font-weight: 600;
                                              position: relative;
                                              display: inline-block;
                                              width: 125px;
                                              text-align: right;
                                          ">
                              {{ LaborCosts[1].money }}
                            </span>
                            万元</span>
                        </a-col>
                        <a-col :span="6">
                          <div class="progress-bar" ref="directCosts" style="height: 50px"></div>
                        </a-col>
                      </a-row>
                    </div>
                  </div>
                </div>
              </div>
              <div class="risk">
                <div class="risk-left">
                  <div class="risk-col-left">当前任务冲刺目标</div>
                  <a-button @click="EditSprint" type="text"
                    style="float: right; top: -25px; font-size: 16px; color: #3875FF">编辑</a-button>

                  <div style="overflow-y: auto; height: 250px; width: 100%;">
                    <a-timeline style=" margin-left: 7px; flex-grow: 1 ;">
                      <a-timeline-item color="#A7B0FB" style=" font-size: 16px" v-for="item in sprintGoalList">
                        <span v-if="sprintGoalList.length > 0" style="font-size: 18px; font-weight: 600">{{ item.month



                        }}月</span>
                        {{ item.sprintGoal }}</a-timeline-item>
                    </a-timeline>
                  </div>
                </div>
                <div class="risk-right">
                  <div class="annex-col">附件</div>
                  <a v-if="false" type="text"
                    style="color: #3875FF; position: absolute; top: 10px; right: 24px; font-size: 16px;"
                    @click="handlerViewAnnex"><paper-clip-outlined style="color:#3875FF" /> 任务附件</a>
                  <div class="annex-box">
                    <div v-for="(item, index) in annexList" class="annex-item">
                      <paper-clip-outlined style="color: #3875FF;" /> <a :href="item.url" :title="item.name"
                        style="color: #3875FF;" target="_blank"> {{ item.name }}</a>
                    </div>
                  </div>
                </div>
              </div>
              <div class="risk-new">
                <div class="risk-col">当前项目风险</div>
                <div class="title-tip">
                  <div class="tag-fx"><a-tag class="parallelogram-risk">风险事件</a-tag>{{ riskData }} </div>
                  <div class="tag-fx"><a-tag class="parallelogram-solution">解决方案</a-tag>{{ riskSolution }}</div>
                </div>
              </div>
              <div class="praise-complaints">
                <div class="praise-col">当前项目表扬投诉情况</div>
                <div class="praise-content">
                  <div class="praise-item" v-for="(item, index) in eventDataSource" :key="index">
                    <div class="praise-item-title">
                      <p class="praise-item-title">{{ item.eventType }} &nbsp;&nbsp;</p>
                    </div>
                    <div class="praise-main">
                      {{ item.incidentDescription }}
                    </div>
                    <div class="praise-annex">
                      <div v-for="(annex, index) in JSON.parse(item.attachment)" class="annex-items">
                        <paper-clip-outlined style="color: #3875FF;" /> <a :href="annex.url" :title="item.attachmentName"
                          style="color: #3875FF;" target="_blank"> {{ annex.name }}</a>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <!-- END 回款里程碑 -->
          </div>
          <a-modal v-model:visible="modalVisible" width="1056px" okText="保存并提交"
            :title="isEdit.value == true ? '编辑' : '新增回款里程碑'" @ok="handlerAdd" @afterClose="handleModalClose">
            <div class="form-div">
              <div v-for="(item, index) in dataList" :key="index">
                <!-- 表单内容 -->
                <a-form label-width="80px" :ref="el => (item.el = el)" :model="item">
                  <a-row>
                    <a-col :span="22">
                      <a-form-item :rules="milestoneNameRule" label="回款里程碑名称" name="paymentMilepostName"
                        :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                        <a-input v-model:value="item.paymentMilepostName" />
                      </a-form-item>
                    </a-col>
                    <a-col :span="2">
                      <div @click="removeIdx(item, index)" class="btn-delete"> 删除 </div>
                    </a-col>
                  </a-row>
                  <a-row>
                    <a-col :span="8">
                      <a-form-item :rules="[{ required: true, message: '请输入金额', trigger: 'blur' }]" label="金额(万元)"
                        name="money" :label-col="{ span: 11 }" :wrapper-col="{ span: 14 }">
                        <a-input-number :min="0" :max="99999999.99" v-model:value="item.money" style="width: 180px" />
                      </a-form-item>
                    </a-col>
                    <a-col :span="7">
                      <a-form-item name="planPaymentTime" label="计划回款时间" :rules="[
                        { required: true, message: '请输入计划回款时间', trigger: 'blur' }
                      ]">
                        <a-date-picker v-model:value="item.planPaymentTime" style="width: 180px"
                          :valueFormat="'YYYY-MM-DD'" />
                      </a-form-item>
                    </a-col>
                    <a-col :span="8">
                      <a-form-item name="actuallyPaymentTime" label="实际回款时间" :label-col="{ span: 8 }"
                        :wrapper-col="{ span: 16 }">
                        <a-date-picker v-model:value="item.actuallyPaymentTime" style="width: 180px"
                          :valueFormat="'YYYY-MM-DD'" />
                      </a-form-item>
                    </a-col>
                  </a-row>
                </a-form>
                <a-divider style="background-color: #3875ff" />
              </div>
            </div>
            <a-button v-if="!isEdit" class="btn-add" @click="addForm"><plus-outlined class="icon" />添加</a-button>
          </a-modal>
          <a-modal v-model:visible="confirmVisible" title="确认提示" @ok="handlerConfirm">
            <p>是否确认完成？</p>
          </a-modal>
          <a-modal v-model:visible="sprintVisible" width="1056px" @ok="handlerEditTarget" title="冲刺目标">
            <div class="form-div">
              <div v-for="(item, index) in sprintTargetList">
                <a-form :model="item" ref="sprintRef">
                  <a-row>
                    <a-col :span="23">
                      <a-form-item :rules="[{ required: true, message: '请输入冲刺目标', trigger: 'blur' }]" label="冲刺目标"
                        name="sprintGoal" :label-col="{ span: 2 }" :wrapper-col="{ span: 22 }">
                        <a-input v-model:value="item.sprintGoal" />
                      </a-form-item>
                    </a-col>
                    <a-col :span="1">
                      <div @click="removeTarget(item, index)" class="btn-delete"> 删除 </div>
                    </a-col>
                  </a-row>
                  <a-row>
                    <a-col :span="8" />
                    <a-col :span="8" />
                    <a-col :span="8">
                      <a-form-item name="month" label="月份"
                        :rules="[{ required: true, message: '请选择月份', trigger: 'blur' }]" :label-col="{ span: 8 }"
                        :wrapper-col="{ span: 16 }">
                        <a-date-picker v-model:value="item.month" style="width: 180px" :valueFormat="'YYYY-MM'"
                          picker="month" />
                      </a-form-item>
                    </a-col>
                  </a-row>
                </a-form>
                <a-divider style="background-color: #3875ff" />
              </div>
              <a-button class="btn-add" @click="addSprintTarget"><plus-outlined class="icon" />添加</a-button>
            </div>
          </a-modal>
          <a-modal v-model:visible="annexVisible" title="任务附件" width="1000px">
            <a-table :columns="annexColumns" :dataSource="annexDataSource" :custom-row="customRow" :scroll="{ x: '800' }">
              <template v-if="column.dataIndex === 'attachment'">
                <template v-if="record.previewPermission">
                  <a v-for="(item, index) in record.ppmEnclosureInfoList" :key="index" href="javascript:"
                    @click="handlerDownload(item)"
                    :class="['block', index > 2 && !record.attachmentShowAll ? 'hide' : '']">
                    {{ item.name }}
                  </a>
                  <a v-if="record.ppmEnclosureInfoList.length > 3 && !record.attachmentShowAll"
                    @click="record.attachmentShowAll = true">更多</a>
                </template>
                <template v-else>
                  <span v-for="(item, index) in record.ppmEnclosureInfoList" :key="index"
                    :class="['block', index > 2 && !record.attachmentShowAll ? 'hide' : '']">
                    {{ item.name }}
                  </span>
                  <a v-if="record.ppmEnclosureInfoList.length > 3 && !record.attachmentShowAll"
                    @click="record.attachmentShowAll = true">更多</a>
                </template>
              </template>
            </a-table>
          </a-modal>
        </div>
        <!-- end vid_iggljq0jjk 自定义模板_wn2w3ezp1c -->
        <!-- begin vid_q6vekc818a 图片_ieklstvdk6 -->
        <al-image v-if="false" class="vid_q6vekc818a"
          :emptyImgSrc="''"
          :src="vid_q6vekc818a_props.src" :width="'101'" :height="'51'" />
        <!-- end vid_q6vekc818a 图片_ieklstvdk6 -->
        <!-- begin vid_7o6phcpz5x 图片_oqh6xufaao -->
        <al-image v-if="false" class="vid_7o6phcpz5x"
          :emptyImgSrc="''"
          :src="vid_7o6phcpz5x_props.src" :width="'520'" :height="'375'" />
        <!-- end vid_7o6phcpz5x 图片_oqh6xufaao -->
        <!-- begin vid_pu1j9824s0 图片_heyc389oe6 -->
        <al-image v-if="false" class="vid_pu1j9824s0"
          :emptyImgSrc="''"
          :src="vid_pu1j9824s0_props.src" :width="'720'" :height="'320'" />
        <!-- end vid_pu1j9824s0 图片_heyc389oe6 -->
        <!-- begin vid_k9j58uih5p 图片_1azohktro2 -->
        <al-image v-if="false" class="vid_k9j58uih5p"
          :emptyImgSrc="''"
          :src="vid_k9j58uih5p_props.src" :width="'720'" :height="'320'" />
        <!-- end vid_k9j58uih5p 图片_1azohktro2 -->
      </al-box>
      <!-- end vid_t24nxlyepr 容器_uff5rjjne5 -->
    </a-spin>
  </div>
</template>
<script setup>
import {
  h, ref, reactive, toRaw, markRaw, watch, computed,
  onBeforeMount, onMounted, onBeforeUnmount, onUnmounted, onActivated, onDeactivated
} from "vue";
import { useRoute, useRouter } from 'vue-router';
const router = useRouter();
const route = useRoute();
import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios';
import {
  cloneDeep, isNullOrEmpty, isEmptyArr, isNullOrUnDef, localGet, isContained, isArray, isEmpty,
  merge, getDifferenceArray, isObject, traversalTreeStructure, checkCaseCondition, renderStringInTemplate, handleBreadcrumbJump, throttle
} from '@/utils/index';
import dayjs from 'dayjs';
import { getPagePcChartsDataSourceConvert } from '@/utils/chart';
import { message, notification, Modal } from 'ant-design-vue'
import { propertyFormatByNumber, propertyFormatByPercentage, propertyFormatByDate } from '@/utils/format';
/*** PUBLISH_EXEGESIS ***
import UserTableRecords from '@/model/UserTableRecords';
*** PUBLISH_EXEGESIS ***/



// 获取传入的流程ID
const props = defineProps({
  processInstanceId: {
    type: String
  }
})
const immediateWatch = (source, callback) => {
  watch(source, callback, { deep: true, immediate: true })
}



/* -------------------------- 属性定义 -------------------------- */

const setTimeOutList = [];
const pageLoading = reactive({
  loading: false,
  tip: undefined
});
const vid_q6vekc818a_imageUrl = 'https://fastdfs-stage.allintechinc.com:8888/group1/M00/02/70/rBUAHWRbQueAEVsRAAAm5eo2304948.png'

const vid_q6vekc818a_props = reactive({
  src: vid_q6vekc818a_imageUrl,
})
const vid_7o6phcpz5x_imageUrl = 'https://fastdfs-stage.allintechinc.com:8888/group1/M00/02/70/rBUAHWRbQuiAMEjOAAFmblmXJcI060.png'

const vid_7o6phcpz5x_props = reactive({
  src: vid_7o6phcpz5x_imageUrl,
})
const vid_pu1j9824s0_imageUrl = 'https://fastdfs-stage.allintechinc.com:8888/group1/M00/02/7A/rBUAHWSlFVyASApnAALow9YhaU8314.png'

const vid_pu1j9824s0_props = reactive({
  src: vid_pu1j9824s0_imageUrl,
})
const vid_k9j58uih5p_imageUrl = 'https://fastdfs-stage.allintechinc.com:8888/group1/M00/02/7A/rBUAHWSlFXSALkxgAANRXv0FOgY191.png'

const vid_k9j58uih5p_props = reactive({
  src: vid_k9j58uih5p_imageUrl,
})



// 处理校验
const setSubFormName = (parentInfo, name) => {
  return [parentInfo.parents, parentInfo.cycleIndex, name];
}


/* ========================== 属性定义 ========================== */


/* -------------------------- 元素数据引用 -------------------------- */


/* ========================== 元素数据引用 ========================== */


/* -------------------------- 页面数据 -------------------------- */

/* ========================== 页面数据 ========================== */


/* -------------------------- 响应 -------------------------- */

/* ========================== 响应 ========================== */


/* -------------------------- 函数 -------------------------- */

/* ========================== 函数 ========================== */


/* -------------------------- 页面参数 -------------------------- */

const pageParameter_state = reactive({
  'processInstanceId': props.processInstanceId,
})

/* ========================== 页面参数 ========================== */


/* -------------------------- 组件事件处理方法 -------------------------- */

// ---------------------------- 组件数据同步 ----------------------------

// ============================ 组件数据同步 ============================


/* ========================== 组件事件处理方法 ========================== */


/* -------------------------- 生命周期 -------------------------- */
onMounted(() => {

});

onUnmounted(() => {
  // 销毁定时器
  setTimeOutList.forEach(({ repeat, timer }) => {
    repeat ? clearInterval(timer) : clearTimeout(timer);
  });
});

/* ========================== 生命周期 ========================== */


/* -------------------------- 数据关联处理 -------------------------- */





/* -------------------------- 表单数据同步 -------------------------- */
/* ========================== 表单数据同步 ========================== */

/* ========================== 数据关联处理 ========================== */


/* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

/* ========================== 不同组件自定义的处理逻辑 ========================== */


// ================================定制化逻辑========================================
import * as echarts from 'echarts'
// 处理校验
let oHead = null;

onMounted(() => {

  let style = document.createElement('style');
  style.setAttribute('id', 'Page520Style');
  style.type = 'text/css';
  style.innerHTML = ".app .left-layout .left-layout__content-wrapper { padding-bottom: 0px; }";
  oHead = document.getElementsByTagName('head').item(0)
  oHead.appendChild(style);

});
onUnmounted(() => {

  let oStyle = document.getElementById('Page520Style');
  oHead.removeChild(oStyle)


});
const milestoneNameRule = [
  { required: true, message: '请输入回款里程碑名称!', trigger: 'blur' },
  {
    validator: (rule, value, callback) => {
      const arr = dataList.value.filter(
        item => item.paymentMilepostName === value && item.paymentMilepostName !== ''
      )
      if (arr.length > 1) {
        return Promise.reject()
      }
      return Promise.resolve()
    },
    message: '里程碑名称重复！',
    trigger: 'blur'
  }
]
const searchValue = ref('')
const editId = ref(null)
const modalVisible = ref(false)
const confirmVisible = ref(false)
const expandedKeys = ref([])
const selectedKeys = ref([])
const fieldNames = { children: 'children', title: 'projectName', key: 'projectId', parentId: 'parentId' }
const dataList = ref(
  // 表单绑定数据
  [
    {
      paymentMilepostName: '',
      money: '',
      planPaymentTime: '',
      actuallyPaymentTime: '',
      el: null
    }
  ]
)
const autoExpandParent = ref(true)
const treeData = ref([])
const treeDataFlatten = ref([])
//数据
const milestoneDataList = ref([])
const collectionList = ref([])
const isEdit = ref(false)
const projectData = ref({
  projectName: '',
  startTime: '',
  endTime: '',
  plName: ''
})
const overlayStyle = {
  width: '326px',
  borderRadius: '4px 4px 4px 0px 2px',
  maxWidth: 'unset',
}
const getTreeData = () => {
  const params = {
    projectName: searchValue.value ? searchValue.value : '', //搜索框
    projectType: '交付'
  }
  post('/ppm/api/v2/built-in-system-ppm/delivery_project/tree/projectList', params).then(data => {
    treeData.value = data.data
  })
}
getTreeData()
// 搜索框变化事件
const onChange = e => {
  getTreeData()
};

// 树选中
const treeSelect = () => {
  if (selectedKeys.value[0]) {
    // 获取项目详情 /ppm/api/v2/built-in-system-ppm/delivery_milepost/list
    get(`/ppm/api/v2/built-in-system-ppm/project/inquiry_project/${selectedKeys.value[0]}`).then(data => {
      projectData.value.projectName = data.projectName
      projectData.value.startTime = data.startTime
      projectData.value.endTime = data.endTime
      projectData.value.plName = data.plName
      getMilepostData()
      getCollectionData()
      // 新需求冲刺
      getSprintData()
      // 回款分析
      getCollectionChartData()
      // 附件
      getAnnexData()
      // 风险事件
      getRiskList()
      // 投诉表扬
      getEventTableData()
    })
  } else {
    message.info('请选择一个项目')
  }
}
const onExpand = keys => {
  expandedKeys.value = keys
  autoExpandParent.value = false
}
// 里程碑数据
const getMilepostData = () => {
  const params = {
    endTime: '',
    projectId: selectedKeys.value[0]
  }
  post('/ppm/api/v2/built-in-system-ppm/v2/milepost/list', params).then(data => {
    milestoneDataList.value = data.data.dataList
    getMilepostChart()
  })
}


function getMilepostChart() {
  setTimeout(() => {
    renderCharts()
  }, 0)

}

function renderCharts() {
  for (let i = 0; i < milestoneDataList.value.length; i++) {
    const chartElement = document.getElementById(`chart${i}`);
    let chart = echarts.init(chartElement);

    const redTasks = milestoneDataList.value[i].percentageOfRedTasks;
    const greenTasks = milestoneDataList.value[i].percentageOfGreenTasks;
    const greyTasks = milestoneDataList.value[i].percentageOfGreyTasks;

    let data;

    if (redTasks === null && greenTasks === null && greyTasks === null) {
      data = [{ value: 1, itemStyle: { color: '#788397', opacity: 0.4 } }];
    } else {
      data = [
        { name: '超期', value: redTasks || 0, itemStyle: { color: '#FF2A00', opacity: 1 } },
        { name: '完成', value: greenTasks || 0, itemStyle: { color: '#38A45A', opacity: 0.8 } },
        { name: '未开始', value: greyTasks || 0, itemStyle: { color: '#788397', opacity: 0.4 } }
      ];
    }

    let option = {
      series: [{
        type: 'pie',
        radius: ['60%', '80%'],
        grid: {
          top: '5px',
          bottom: '5px',
          left: '5px',
          right: '5px'
        },
        labelLine: {
          show: false
        },
        data: data
      }]
    };

    chart.setOption(option);
  }
}

// 回款里程碑数据
const getCollectionData = () => {
  const params = {
    milepostId: selectedKeys.value[0]
  }
  post('/ppm/api/v2/built-in-system-ppm/payment-milepost/list', params).then(data => {
    collectionList.value = data.data
  })
}
let addForm = () => {
  dataList.value.push({
    paymentMilepostName: '',
    money: '',
    planPaymentTime: '',
    actuallyPaymentTime: '',
    el: null
  })
}
// 删除操作
let removeIdx = (item, index) => {
  dataList.value.splice(index, 1)
}
// 添加
let addCollection = () => {
  if (selectedKeys.value.length > 0) {
    isEdit.value = false
    modalVisible.value = true
    dataList.value = [
      {
        paymentMilepostName: '',
        money: '',
        planPaymentTime: '',
        actuallyPaymentTime: '',
        el: null
      }
    ]
  } else {
    message.info('请选择项目')
  }

}
// 编辑
let editCollection = () => {
  if (selectedKeys.value.length > 0) {
    isEdit.value = true
    const params = {
      milepostId: selectedKeys.value[0]
    }
    post('/ppm/api/v2/built-in-system-ppm/payment-milepost/list', params).then(data => {
      dataList.value = data.data.map(item => {
        return {
          paymentMilepostName: item.paymentMilepostName,
          money: item.money,
          planPaymentTime: item.currentPlanTime,
          actuallyPaymentTime: item.actuallyPaymentTime,
          el: null,
          id: item.id
        }
      })
      modalVisible.value = true

    })
  } else {
    message.info('请选择项目')
  }

}

// 完成按钮
let confirm = id => {
  editId.value = id
  confirmVisible.value = true
}
const handlerConfirm = () => {
  post(`/ppm/api/v2/built-in-system-ppm/payment-milepost/finish/${editId.value}`).then(() => {
    confirmVisible.value = false
    getCollectionData()
    editId.value = null
  })
}
// 提交
const handlerAdd = () => {
  if (isEdit.value !== true) {
    for (let i = 0; i < dataList.value.length; i++) {
      let item = dataList.value[i]
      if (!item.paymentMilepostName || !item.money || !item.planPaymentTime) {
        message.info('请检查表单项是否填写完整')
        return
      }
    }
    const params = {
      milepostId: selectedKeys.value[0],
      ppmPaymentMilepostFormList: dataList.value
    }
    post('/ppm/api/v2/built-in-system-ppm/payment-milepost/add', params).then(data => {
      if (data.code === 200) {
        message.success('添加成功')
        modalVisible.value = false
        getCollectionData()
        getCollectionChartData()
      } else {
        message.error(data.message)
      }
    })
  } else {
    for (let i = 0; i < dataList.value.length; i++) {
      let item = dataList.value[i]
      if (!item.paymentMilepostName || !item.money || !item.planPaymentTime) {
        message.info('请检查表单项是否填写完整')
        return
      }
    }
    const params = {
      milepostId: selectedKeys.value[0],
      ppmPaymentMilepostFormList: dataList.value
    }
    post('/ppm/api/v2/built-in-system-ppm/payment-milepost/edit', params).then(data => {
      if (data.code === 200) {
        message.success('修改成功')
        getCollectionData()
        modalVisible.value = false
        isEdit.value = false
        getCollectionChartData()
      } else {
        message.error(data.message)
      }
    })
  }
}
const handleModalClose = () => {
  for (let i = 0; i < dataList.value.length; i++) {
    dataList.value[i].el.resetFields()
  }
  // 清空表单
}


//新需求
const moneyStyle = {
  fontSize: '30px',
  fontWeight: '800'
}
const annexList = ref([])
const costChart = ref(null)
const primeChart = ref(null)
const progressBar = ref(null)
const directCosts = ref(null)
const sprintRef = ref(null)
const sprintVisible = ref(true)
const annexVisible = ref(false)
// 附件表格
const annexColumns = [
  {
    title: '项目阶段名称',
    dataIndex: 'milepostName',
    resizable: true,
    key: 'milepostName',
    width: '200px',
    customCell: ({ rowSpan }) => {
      return {
        rowSpan: rowSpan
      }
    }
  },
  {
    title: '任务名称',
    dataIndex: 'taskName',
    width: '200px',
    resizable: true,
  },
  {
    title: '附件',
    dataIndex: 'attachment',
    resizable: true,
    width: '200px',
  },
]
const annexDataSource = ref([])
// 回款分析图数据
const collectionMoneyData = ref([])
// 回款分析项目总金额
const totalProjectAmount = ref(null)
// 项目预算
const projectBudget = ref([
  { value: 511.7711, name: '总人力成本' },
  { value: 981.8211, name: '总直接成本' }
])
// 项目预算
const projectBudgetAmount = ref(489.1119)
// 人力图表
const LaborCosts = ref([
  {
    value: 93, name: '已发生人力成本', money: 986.1198
  },
  {
    value: 98, name: '已发生直接费用', money: 189.1114
  }
])
// 冲刺目标
const sprintTargetList = ref([
  {
    sprintGoal: '',
    month: "",
    id: null
  }
])
const sprintGoalList = ref([])
// 风险
const riskData = ref('')

const riskSolution = ref('')
let EditSprint = () => {
  if (selectedKeys.value.length == 0) {
    message.info('请选择一个项目')
  } else {
    get(`/ppm/api/v2/built-in-system-ppm/v2/project/findSprintGoalByProjectId/${selectedKeys.value[0]}`).then(data => {
      sprintTargetList.value = data.data
      sprintVisible.value = true
    })
  }

}
let addSprintTarget = () => {
  sprintTargetList.value.push({
    sprintGoal: '',
    month: '',
    id: null
  })
}
let removeTarget = (item, index) => {
  sprintTargetList.value.splice(index, 1)
}
let handlerEditTarget = () => {
  for (let i = 0; i < sprintTargetList.value.length; i++) {
    let item = sprintTargetList.value[i]
    if (!item.sprintGoal || !item.month) {
      message.error(`请补充第${i + 1}条数据`)
      return
    }
  }
  const params = {
    projectId: selectedKeys.value[0],
    ppmProjectSprintGoalList: sprintTargetList.value
  }
  post('/ppm/api/v2/built-in-system-ppm/v2/project/saveOrUpdate', params).then(data => {
    if (data.code === 200) {
      message.success('编辑成功')
      sprintVisible.value = false
      getSprintData()
    } else {
      message.error(data.message)
    }
  })
}
let getProjectAmount = () => {
  // 获取DOM元素
  const chartDom = costChart.value
  // 基于DOM元素初始化ECharts实例
  const myChart = echarts.init(chartDom)
  // 设置环形图的数据和样式
  myChart.setOption({
    color: ['#3875FF', '#FF8448'],
    tooltip: {
      trigger: 'item'
    },
    title: [
      {
        text: `{a|合同总金额}\n{b|${totalProjectAmount.value}}\n{c|万元}`, // 设置标题文本，并使用富文本标签
        left: '50%',
        textAlign: 'center',
        bottom: 'center',
        textStyle: {
          rich: {
            // 定义富文本标签的样式
            a: {
              color: 'black',
              fontSize: 16, // 合同总金额的字体大小
              lineHeight: 24 // 设置行高为 24，实现行间距效果
            },
            b: {
              color: 'black',
              fontWeight: 600,
              fontSize: 25, // 10000的字体大小
              lineHeight: 36 // 设置行高为 36，实现行间距效果
            },
            c: {
              color: 'black',
              fontSize: 16, // 万元的字体大小
              lineHeight: 24 // 设置行高为 24，实现行间距效果
            }
          }
        }
      }
    ],
    series: [
      {
        type: 'pie',
        radius: ['66%', '76%'],
        center: ['50%', '50%'],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 0,
          borderColor: '#fff',
          borderWidth: 2
        },
        label: {
          show: false,
          position: 'center'
        },
        labelLine: {
          show: false
        },
        data: collectionMoneyData.value
      }
    ]
  })
}
// 新需求冲刺
let getSprintData = () => {
  get(`/ppm/api/v2/built-in-system-ppm/v2/project/findSprintGoalByProjectId/${selectedKeys.value[0]}`).then(data => {
    sprintGoalList.value = data.data
  })
}
// 附件
let getAnnexData = () => {
  get(`/ppm/api/v2/built-in-system-ppm/v2/project/list/${selectedKeys.value[0]}`).then(data => {
    annexList.value = data.data
  })
}
// 成本分析
let getCollectionChartData = () => {
  get(`/ppm/api/v2/built-in-system-ppm/payment-milepost/listByProject/${selectedKeys.value[0]}`).then(data => {
    collectionMoneyData.value = data.data ? data.data.paymentStatus : []
    totalProjectAmount.value = data.data ? data.data.money : null
    // 成本分析图表
    getProjectAmount()
  })
}
// 风险事件
let getRiskList = () => {
  get(`/ppm/api/v2/built-in-system-ppm/v2/project/getLatestExtremeRisk/${selectedKeys.value[0]}`).then(data => {
    riskData.value = data.data ? data.data.riskDescription : ''
    riskSolution.value = data.data ? data.data.solution : ''
  })
}

// let getChartData = () => {

//   getPrimeChart()
//   getCostChart()
//   getDirectChart()
// }
// end新需求

// 成本分析
let getPrimeChart = () => {
  // 获取DOM元素
  const chartDom = primeChart.value
  // 基于DOM元素初始化ECharts实例
  const myChart = echarts.init(chartDom)
  // 设置环形图的数据和样式
  myChart.setOption({
    color: ['#3875FF', '#FF8448'],
    tooltip: {
      trigger: 'item'
    },

    title: [
      {
        text: `{a|项目总预算}\n{b|${projectBudgetAmount.value}}\n{c|万元}`, // 设置标题文本，并使用富文本标签
        left: '50%',
        textAlign: 'center',
        bottom: 'center',
        textStyle: {
          rich: {
            // 定义富文本标签的样式
            a: {
              color: 'black',
              fontSize: 16, // 合同总金额的字体大小
              lineHeight: 24 // 设置行高为 24，实现行间距效果
            },
            b: {
              color: 'black',
              fontWeight: 600,
              fontSize: 25, // 10000的字体大小
              lineHeight: 36 // 设置行高为 36，实现行间距效果
            },
            c: {
              color: 'black',
              fontSize: 16, // 万元的字体大小
              lineHeight: 24 // 设置行高为 24，实现行间距效果
            }
          }
        }
      }
    ],
    series: [
      {
        type: 'pie',
        radius: ['66%', '76%'],
        center: ['50%', '50%'],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 0,
          borderColor: '#fff',
          borderWidth: 2
        },
        label: {
          show: false,
          position: 'center'
        },
        labelLine: {
          show: false
        },
        data: projectBudget.value
      }
    ]
  })
}

let getCostChart = () => {
  const chart = echarts.init(progressBar.value)
  chart.setOption({
    tooltip: {
      show: true
    },
    grid: {
      top: '20%', // 设置上边距为 20%
      bottom: '20%' // 设置下边距为 20%
    },
    xAxis: {
      type: 'value',
      show: false
    },
    yAxis: {
      type: 'category',
      data: ['进度条'],
      show: false
    },
    series: [
      {
        type: 'bar',
        center: ['0%', '60%'],
        data: [
          {
            value: LaborCosts.value[0].value,
            itemStyle: {
              color: '#FF2A00'
            }
          }
        ],
        barWidth: 10,
        label: {
          show: true,
          position: 'right',
          formatter: '{c}%',
          position: ['80%', '10%']
        },
        itemStyle: {
          barBorderRadius: 50
        },
        tooltip: {
          show: false
        },
        backgroundStyle: {
          color: '#ddd'
        },
        progress: {
          show: true,
          width: 20,
          itemStyle: {
            color: '#62c87f',
            borderWidth: 0,
            borderRadius: 10
          }
        }
      }
    ]
  })
}
let getDirectChart = () => {
  const chart = echarts.init(directCosts.value)
  chart.setOption({
    tooltip: {
      show: true
    },
    grid: {
      top: '20%', // 设置上边距为 20%
      bottom: '20%' // 设置下边距为 20%
    },
    xAxis: {
      type: 'value',
      show: false
    },
    yAxis: {
      type: 'category',
      data: ['进度条'],
      show: false
    },
    series: [
      {
        type: 'bar',
        center: ['0%', '50%'],
        data: [
          {
            value: LaborCosts.value[1].value,
            itemStyle: {
              color: '#07AB99'
            }
          }
        ],
        barWidth: 10,
        label: {
          show: true,
          position: 'right',
          formatter: '{c}%',
          position: ['80%', '10%']
        },
        itemStyle: {
          barBorderRadius: 50
        },
        tooltip: {
          show: false
        },
        backgroundStyle: {
          color: '#ddd'
        },
        progress: {
          show: true,
          width: 20,
          itemStyle: {
            color: '#62c87f',
            borderWidth: 0,
            borderRadius: 10
          }
        }
      }
    ]
  })
}
// 任务附件
function handlerViewAnnex() {
  annexVisible.value = true
  groupData(annexDataSource.value)
}
// 下载附件
function handlerDownload({ url, name }) {
  function downBlob(blob) {
    const downloadElement = document.createElement('a')
    const href = window.URL.createObjectURL(blob) // 创建下载的链接
    downloadElement.href = href
    downloadElement.download = name // 下载后文件名
    document.body.appendChild(downloadElement)
    downloadElement.click() // 点击下载
    document.body.removeChild(downloadElement) // 下载完成移除元素
    window.URL.revokeObjectURL(href)
  }
  const data = new FormData()
  data.append('path', url)
  post('/ppm/api/v2/built-in-system-ppm/delivery_task/downloadFile', data, {
    responseType: 'blob',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  }).then(blob => {
    downBlob(blob)
  })
}
// 合并单元格
function groupData(data) {
  //声明一个新字段
  let currentMilepostName = ''
  return data.map((item, index) => {
    if (currentMilepostName !== item.milepostName) {
      currentMilepostName = item.milepostName
      let rowSpan = 0
      for (let i = 0; i < data.length; i++) {
        if (i >= index) {
          if (currentMilepostName === data[i].milepostName) {
            rowSpan += 1
          } else {
            break
          }
        }
      }
      item.rowSpan = rowSpan
    } else {
      item.rowSpan = 0
    }

    return item
  })
}
const eventDataSource = ref([])
// 获取投诉表扬
let getEventTableData = () => {
  const params = {
    projectId: selectedKeys.value[0]
  }
  post(`/ppm/api/v2/built-in-system-ppm/praiseComplaint/queryPpmPraiseComplaintData`, params).then(data => {
    if (data.code === 200) {
      eventDataSource.value = data.data
    }
  })
}

// 监听 eventDataSource.value 的变化
watch(
  () => eventDataSource.value,
  () => {
    console.log(eventDataSource.value.length);

    // 设置 .praise-complaints 的高度
    const ts = document.querySelector('.praise-complaints');
    ts.style.height = `${eventDataSource.value.length * 15}vh`;
  }
);
</script>
<style lang="less" scoped>
.page_root {
  width: 100%;
  height: 100%;
  overflow: auto;
  margin-top: 0px;
  margin-right: 0px;
  margin-bottom: 0px;
  margin-left: 0px;
  padding-top: 0px;
  padding-right: undefinedpx;
  padding-bottom: 0px;
  padding-left: undefinedpx;
}

.page_root :deep(.@{ant-prefix}-spin-nested-loading),
.page_root :deep(.@{ant-prefix}-spin-container) {
  height: 100%;
}

.table-moreBtn_down {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  width: 100px;
}

.table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
  background: #ebf1ff;
}

/*  表格树结构样式处理，展开按钮层级增加*/
:deep(.@{ant-prefix}-table-row-expand-icon) {
  z-index: 1;
}

/*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
:deep(.@{ant-prefix}-table-row-level-1 .ant-table-cell-with-append .cell-wrapper-left) {
  left: 15px !important;
  width: calc(100% - 15px);
}

:deep(.@{ant-prefix}-table-row-level-2 .ant-table-cell-with-append .cell-wrapper-left) {
  left: 30px !important;
  width: calc(100% - 30px);
}

:deep(.@{ant-prefix}-table-row-level-3 .ant-table-cell-with-append .cell-wrapper-left) {
  left: 45px !important;
  width: calc(100% - 45px);
}

:deep(.@{ant-prefix}-table-row-level-4 .ant-table-cell-with-append .cell-wrapper-left) {
  left: 60px !important;
  width: calc(100% - 60px);
}

/* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
:deep(.@{ant-prefix}-transfer-list) {
  height: 100%;
  width: 50%;
}

.vid_t24nxlyepr {
  width: 100%;
  height: 922px;
  display: block
}

.page_root {
  overflow: hidden !important;
}

.body {
  background-color: #f6f6fa;
  display: flex;
}

.body .col {
  padding: 0 20px 0 20px;
  position: relative;
  font-size: 18px;
  font-weight: 800;
  margin-top: 5px;
  left: -10px
}

.body .col:before {
  content: '';
  background-color: #3875ff;
  width: 5px;
  height: 18px;
  position: absolute;
  left: -10px;
  top: 75%;
  margin-left: 20px;
  margin-top: -15px;
}

.body .collection-col {
  padding: 0 20px;
  position: relative;
  font-size: 18px;
  font-weight: 800;
  margin-top: 5px;
  margin-left: 12px;
}

.body .collection-col:before {
  content: '';
  background-color: #3875ff;
  width: 5px;
  height: 18px;
  position: absolute;
  left: -10px;
  top: 75%;
  margin-left: 20px;
  margin-top: -15px;
}

.body .tree-box {
  overflow-y: scroll;
  min-height: 820px;
  width: 200px;
  padding: 10px;
  background-color: #fff;
  overflow: auto;
  height: 100vh;
}

.body .right-box {
  flex: 1;
  height: 100vh;
  min-width: 0;
  overflow: auto;
}

.body .right-box .back-ground {
  height: 80px;
  padding: 10px 24px;
  font-size: 24px;
  color: #fff;
  line-height: 30px;
  font-weight: 400;
  background: linear-gradient(to right, #3f48f4, #76a0ff);
}

.body .right-box .back-ground .title {
  font-size: 18px;
  font-weight: 400;
  margin-left: 16px;
}

.body .right-box .main {
  position: relative;
  top: -35px;
  height: 100%;
  padding: 0 24px;
}

.body .right-box .progress {
  padding: 0 20px 20px 20px;
  border: 2px solid #fff;
  border-radius: 10px;
  background-color: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(6px);
  margin-bottom: 24px;
}

.body .right-box .progress .timeaxis {
  width: 100%;
  margin-top: 60px;
  display: flex;
  flex-flow: wrap;
}

.body .right-box .progress .no-progress {
  height: 370px;
  width: 100%;
  background-color: #fff;
  display: flex;
  justify-content: center;
  border: 1px solid #fff;
  border-radius: 10px;
  position: relative;
  margin-top: 10px;
  /* 水平居中 */
}

.body .right-box .progress .no-progress .tip {
  width: 200px;
  height: 101px;
  background-image: url('https://fastdfs-stage.allintechinc.com:8888/group1/M00/02/70/rBUAHWRbQuaAMz-_AAAm5eo2304667.png');
  position: absolute;
  top: 30%;
}

.body .right-box .progress .no-progress .tip .message {
  position: absolute;
  left: 22%;
  bottom: -40px;
  font-size: 16px;
}

.body .right-box .progress .box:nth-child(-n + 5) {
  width: 20%;
  margin: 0;
}

.body .right-box .progress .box:nth-child(n + 11) {
  width: 20%;
  margin-top: 63px;
}

.body .right-box .progress .box {
  width: 20%;
  margin-top: 55px;
}

.body .right-box .progress .box:nth-child(n + 6) .detailed-information .message {
  margin-bottom: 0;
}

.body .right-box .progress .box .item {
  border-bottom: 3px solid #3f79ff;
  position: relative;
}

.body .right-box .progress .box .item .cercle {
  position: absolute;
  width: 25px;
  height: 25px;
  border-radius: 25px;
  background-color: #3f79ff;
  top: -11px;
  left: 0;
}

.body .right-box .progress .box .item .arrow {
  position: absolute;
  font-size: 35px;
  color: #3f79ff;
  top: -16px;
  right: -15px;
}

.body .right-box .progress .box .item .center {
  width: 100%;
  font-size: 16px;
  text-align: center;
  position: absolute;
  font-weight: 600;
  top: -55px;
}

.body .right-box .progress .circular {
  width: 50px;
  height: 50px;
  background: white;
  margin: auto;
  margin-bottom: -4px;
  position: relative;
  top: -13px;
}

.body .right-box .progress .detailed-information {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}

.body .right-box .progress .detailed-information .message {
  flex: 1;
  width: 20%;
  background: linear-gradient(to bottom, #f3f7fa, #ffffff);
  border-radius: 8px;
  height: 114px;
  margin: 0 8px;
  padding: 10px;
  box-shadow: 0 4px 4px #eff0f1;
  display: flex;
  flex-direction: column;
  position: relative;
  margin-bottom: 10px;
}

.body .right-box .progress .detailed-information .message p {
  flex: 1;
}

.body .right-box .progress .detailed-information .message .plan {
  font-size: 15px;
  margin: 0;
  font-weight: normal;
  display: flex;
  align-items: center;
}

.body .right-box .progress .detailed-information .message .plan-count {
  position: absolute;
  border-radius: 2px 8px 2px 8px;
  top: 0;
  right: -8px;
}

.body .right-box .progress .detailed-information .message .tag-day {
  border-radius: 10px;
  margin: 0;
}

.body .right-box .no-collection {
  height: 280px;
  width: 100%;
  border: 1px solid #fff;
  border-radius: 10px;
  background-color: #fff;
  display: flex;
  justify-content: center;
  /* 水平居中 */
  /* 垂直居中 */
}

.body .right-box .no-collection .tip {
  width: 200px;
  height: 101px;
  background-image: url('https://fastdfs-stage.allintechinc.com:8888/group1/M00/02/70/rBUAHWRbQuaAMz-_AAAm5eo2304667.png');
  position: relative;
  top: 20%;
}

.body .right-box .no-collection .tip .message {
  width: 250px;
  position: absolute;
  left: -4%;
  bottom: -40px;
  font-size: 16px;
}

.body .right-box .no-collection .tip .message span {
  color: #3875ff;
}

.body .right-box .collection {
  position: relative;
  width: 100%;
  border: 1px solid #fff;
  border-radius: 10px;
  background-color: #fff;
}

.body .right-box .collection .add-edit-btns {
  width: 150px;
  display: flex;
  height: 30px;
  line-height: 30px;
  position: absolute;
  right: -18px;
  top: 5px;
  z-index: 999;
}

.body .right-box .collection .add-edit-btns .collection-btn {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  margin: 0 10px 0 0;
  font-size: 16px;
  color: #3875ff;
  vertical-align: middle;
  cursor: pointer;
}

.body .right-box .collection .add-edit-btns .collection-btn .icon {
  position: absolute;
  top: 8px;
  right: 70px;
  cursor: pointer;
}

.body .collection-message-group {
  padding: 0 12px 0 12px;
  display: flex;
  flex-flow: wrap;
}

.body .collection-message-group .collection-message {
  width: calc(25% - 24px);
  height: 211px;
  padding: 16px 20px;
  flex-shrink: 0;
  margin: 5px 12px 20px 12px;
  border: 1px solid #e2e9f6;
  box-shadow: 1px 1px 1px #e2e9f6;
  border-radius: 8px;
  background-color: #fff;
  position: relative;
  overflow: hidden;
}

.body .collection-message-group .collection-message .order {
  width: 150px;
  position: absolute;
  right: -45px;
  top: -70px;
  font-size: 180px;
  z-index: 1;
  background: linear-gradient(to bottom, #f5f6fa, rgba(251, 251, 253, 0));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  font-family: 'SimHei-ExtB', Arial, sans-serif;
  font-weight: bold;
  -webkit-transform: skew(-10deg);
  /* for Chrome||Safari */
  -ms-transform: skew(-10deg);
  /* for IE */
  -moz-transform: skew(-10deg);
  /* for Firefox */
  -o-transform: skew(-10deg);
  /* for Opera */
}

.body .collection-message-group .collection-message .collection-message-title {
  position: relative;
  font-size: 16px;
  font-weight: 800;
  margin-bottom: 0;
  height: 38px;
  z-index: 999;
  cursor: pointer;
  width: 280px;
  overflow: hidden;
  /*超出部分隐藏*/
  text-overflow: ellipsis;
  /*超出部分省略号表示*/
  white-space: nowrap;
  /*强制单行显示*/
  display: inline-block;
  /*转换为行内块元素*/
}

.body .collection-message-group .collection-message .payment-received {
  font-size: 16px;
  font-weight: 600;
  color: #06ab9a;
  cursor: pointer;
}

.body .collection-message-group .collection-message .payment-received .title {
  display: inline-block;
  width: 73px;
  text-align: right;
  position: relative;
  cursor: pointer;
}

.body .collection-message-group .collection-message .payment-received .title .icon {
  font-size: 20px;
  position: absolute;
  top: 3px;
  left: 0;
  cursor: pointer;
}

.body .collection-message-group .collection-message .payment-received .finish-money {
  margin: 0 0 0 5px;
  font-size: 30px;
  cursor: pointer;
}

.body .collection-message-group .collection-message .payment-received .finish-unit {
  margin: 0 0 0 5px;
  font-size: 16px;
  cursor: pointer;
}

.body .collection-message-group .collection-message .tobe-collected-received {
  font-size: 16px;
  font-weight: 600;
  color: #ff2a00;
  margin-bottom: 0;
  cursor: pointer;
}

.body .collection-message-group .collection-message .tobe-collected-received .fail-money {
  font-size: 30px;
  margin: 0 0 0 5px;
  cursor: pointer;
}

.body .collection-message-group .collection-message .tobe-collected-received .fail-unit {
  font-size: 16px;
  margin: 0 0 0 5px;
  cursor: pointer;
}

.body .collection-message-group .collection-message .uncollected-payment {
  font-size: 16px;
  font-weight: 600;
  color: #788398;
  margin-bottom: 0;
  cursor: pointer;
}

.body .collection-message-group .collection-message .uncollected-payment .uncollected-money {
  margin: 0 0 0 5px;
  font-size: 30px;
  cursor: pointer;
}

.body .collection-message-group .collection-message .uncollected-payment .uncollected-unit {
  margin: 0 0 0 5px;
  font-size: 16px;
  cursor: pointer;
}

.body .collection-message-group .collection-message .divider-line {
  margin: 15px 0 5px 0;
  background-color: #c4c9cf;
}

.body .collection-message-group .collection-message .milepost-date {
  font-size: 16px;
  color: #42526e;
  margin: 0;
}

.body .collection-message-group .collection-message .accomplish {
  position: absolute;
  bottom: 16px;
  right: 16px;
  z-index: 999;
}

.body .collection-message-group .collection-message .noAccomplish {
  position: absolute;
  bottom: 13px;
  right: 16px;
  color: #3875ff;
  z-index: 999;
}

.btn-delete {
  width: 30px;
  position: relative;
  color: #3875ff;
  cursor: pointer;
  top: -4px;
  left: 12px;
}

.btn-delete .icon {
  position: absolute;
  top: 4px;
  right: 35px;
  cursor: pointer;
}

.btn-add {
  border-color: #3875ff;
  margin-left: 20px;
  position: relative;
  color: #3875ff;
  cursor: pointer;
}

.btn-add .icon {
  position: absolute;
  top: 7px;
  left: 5px;
  cursor: pointer;
}

/deep/ .ant3-tag {
  border: none;
  background-color: rgba(255, 42, 0, 0.1);
  color: #ff2a00;
}

/deep/ .ant-tag {
  border: none;
  background-color: rgba(255, 42, 0, 0.1);
  color: #ff2a00;
}

/deep/ .ant3-tree-list-holder-inner {
  position: relative;
}

/deep/ .ant3-tree-list-holder-inner svg {
  position: absolute;
  top: 6px;
  left: 6px;
}

/deep/.left-layout .left-layout__content-wrapper {
  padding: 0 24px;
}

.form-div {
  max-height: 680px;
  overflow-y: auto;
}

.tip-tool p {

  margin-bottom: 12px;

}


.cost-analysis {
  margin-top: 24px;
  height: 240px;
  display: flex;
}

.cost-analysis .collection-analysis {
  width: 35%;
  background-color: #fff;
  border-radius: 10px;
  margin-right: 20px;
  padding: 0 20px;
}

.cost-analysis .cost-col {
  padding: 0 10px;
  position: relative;
  font-size: 18px;
  font-weight: 800;
  margin-top: 5px;
}

.cost-analysis .cost-col:before {
  content: '';
  background-color: #3875ff;
  width: 5px;
  height: 18px;
  position: absolute;
  left: -10px;
  top: 75%;
  margin-left: 10px;
  margin-top: -15px;
}

.cost-analysis .prime-analysis {
  background-color: #fff;
  border-radius: 10px;
  flex: 1;
  padding: 0 0 0 20px;
}

.cost-analysis .prime-analysis .content-cost {
  display: flex;
  justify-content: space-between;
}

.cost-analysis .prime-analysis .content-cost .right-chart {
  width: 60%;
  height: 200px;
  display: flex;
}

.cost-analysis .prime-analysis .content-cost .prime-right {
  width: 50%;
  height: 144px;
  padding: 20px 10px 20px 20px;
  border-radius: 8px;
  margin-top: 28px;
  margin-right: 30px;
  background-image: linear-gradient(180deg, #f5f6fa 0%, rgba(251, 251, 253, 0) 100%);
}

.left-cost-chart {
  display: flex;
}

.progress-bar {
  top: 3px;
  left: -5px;
}

.risk {
  display: flex;
  justify-content: space-between;
  min-height: 320px;
  margin-top: 24px;
  margin-bottom: 24px;
  border-radius: 10px;
}

.risk-left {
  width: 50%;
  min-height: 320px;
  background-color: #fff;
  margin-right: 20px;
  border-radius: 10px;
  padding: 0 20px;
  background-image: url('https://fastdfs-stage.allintechinc.com:8888/group1/M00/02/7A/rBUAHWSlFXSALkxgAANRXv0FOgY191.png');
  overflow-y: auto;
  background-repeat: no-repeat;
}

.risk-right {
  position: relative;
  height: 320px;
  flex: 1;
  border-radius: 10px;
  background-image: url('https://fastdfs-stage.allintechinc.com:8888/group1/M00/02/7A/rBUAHWSlFVyASApnAALow9YhaU8314.png');
}


.risk-new {
  background-color: #fff;
  border-radius: 8px;
  min-height: 245px;
  margin-bottom: 24px;
  padding-bottom: 24px;
}

.title-tip {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: space-around;
  width: 98%;
  min-height: 150px;
  margin: 16px 0 0 24px;
  border-left: 4px solid #ff2a00;
  background-image: linear-gradient(270deg, rgba(255, 42, 0, 0) 0%, rgba(255, 42, 0, 0.1) 100%);
  padding-left: 4px;
}

.praise-complaints {
  background-color: #fff;
  border-radius: 8px;
  min-height: 300px;
}

.praise-item {
  letter-spacing: 0;
  padding: 24px;
  width: 49%;
  border: 1px solid #DEE8F4;
  min-height: 135px;
  border-radius: 10px;
  margin-bottom: 15px;
}

.praise-item-title {
  font-family: 'PingFangSC-Regular';
  color: #192842;
  font-size: 16px;
  font-weight: 600;
  margin-right: 12px;
}

.praise-item-title {
  margin-bottom: 16px;
}

.praise-item-title-time-title {
  font-weight: 400;
  font-size: 14px;
  color: #788397;
}

.praise-item-title-time {
  font-size: 14px;
  color: #192842;
}

.praise-main {
  margin-bottom: 16px;
}

.praise-annex {
  display: flex;
  justify-content: start;
}

.annex-items {
  margin-right: 10px;
}

.praise-content {
  margin-top: 16px;
  padding: 0 24px;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;

}


.risk-col {
  top: 5px;
  left: 24px;
  padding: 0 10px;
  position: relative;
  font-size: 18px;
  font-weight: 800;
}

.risk-col:before {
  content: '';
  background-color: #3875ff;
  width: 5px;
  height: 18px;
  position: absolute;
  left: -10px;
  top: 75%;
  margin-left: 10px;
  margin-top: -15px;
}

.praise-col {
  top: 5px;
  left: 24px;
  padding: 0 10px;
  position: relative;
  font-size: 18px;
  font-weight: 800;
}

.praise-col:before {
  content: '';
  background-color: #3875ff;
  width: 5px;
  height: 18px;
  position: absolute;
  left: -10px;
  top: 21px;
  margin-left: 10px;
  margin-top: -15px;
}

.annex-col {
  top: 5px;
  padding: 0 10px;
  position: relative;
  font-size: 18px;
  font-weight: 800;
  left: 24px;
}

.annex-col:before {
  content: '';
  background-color: #3875ff;
  width: 5px;
  height: 18px;
  position: absolute;
  left: -10px;
  top: 75%;
  margin-left: 10px;
  margin-top: -15px;
}

.risk-col-left {
  top: 5px;
  padding: 0 10px;
  position: relative;
  font-size: 18px;
  font-weight: 800;
}

.risk-col-left:before {
  content: '';
  background-color: #3875ff;
  width: 5px;
  height: 18px;
  position: absolute;
  left: -10px;
  top: 75%;
  margin-left: 10px;
  margin-top: -15px;
}

.annex-box {
  height: 90%;
  overflow-y: scroll;
}

.annex-item {
  font-size: 14px;
  margin-top: 30px;
  margin-left: 24px;
}

.tag-fx {
  height: 50%;
  padding: 10px;
}

.parallelogram-risk {
  width: 62px;
  height: 20px;
  border: 1px solid #ff2a00;
  color: #fd3915;
  transform: skewX(-7deg);
}

.parallelogram-solution {
  width: 62px;
  height: 20px;
  border: 1px solid #3875ff;
  color: #3875ff;
  transform: skewX(-7deg);
}

/deep/ .ant3-timeline-item-tail {
  border-left: 2px dotted #a6b0fb;
}

/deep/.ant3-timeline-item-head {
  width: 8px;
  height: 8px;
  background-color: #a6b0fb;
  left: 1px;
}

.hr-money {
  background: linear-gradient(to right, #e1e4ed 0%, #e1e4ed 50%, #e1e4ed 100%);
  height: 2px;
  width: 250px;
}

/deep/.ant3-table-thead tr th {
  background-color: #3875ff;
  color: #fff;
  font-weight: 600;
  padding: 14px 20px;
}

/deep/ tr:nth-child(odd),
/deep/ tr:nth-child(odd) td {
  background: #F8FAFC;
  padding: 14px 20px;
}
</style>